package library.common.util.permission;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;

import io.reactivex.functions.Consumer;
import library.common.R;

/**
 * @author Created by qiang.hou on 2018/12/6.
 * @version 1.0
 */
public class RxPermissionChecker {
    private FragmentActivity activity;
    private Fragment fragment;

    private IOnPermissionGrant grantCallback;
    private IOnPermissionDenied deniedCallback;

    private int settingActivityRequestCode;

    private DialogInterface.OnCancelListener onDefaultDeniedDialogCancelListener;

    public RxPermissionChecker activity(FragmentActivity activity) {
        this.activity = activity;
        return this;
    }

    public RxPermissionChecker fragmentV4(Fragment fragmentV4) {
        this.fragment = fragmentV4;
        return this;
    }

    public RxPermissionChecker grantCallback(IOnPermissionGrant grantCallback) {
        this.grantCallback = grantCallback;
        return this;
    }

    public RxPermissionChecker deniedCallback(IOnPermissionDenied deniedCallback) {
        this.deniedCallback = deniedCallback;
        return this;
    }

    public RxPermissionChecker settingActivityRequestCode(int settingActivityRequestCode) {
        this.settingActivityRequestCode = settingActivityRequestCode;
        return this;
    }

    public RxPermissionChecker onDefaultDeniedDialogCancelListener(DialogInterface.OnCancelListener onCancelListener) {
        this.onDefaultDeniedDialogCancelListener = onCancelListener;
        return this;
    }

    @SuppressLint("CheckResult")
    public void requestPermission(String... permissions) {
        if (null != activity) {
            new RxPermissionsV4(activity)
                    .requestEach(permissions)
                    .subscribe(new Consumer<Permission>() {
                        @Override
                        public void accept(Permission permission) {
                            if (null != permission) {
                                if (permission.granted) {
                                    if (null != grantCallback) {
                                        grantCallback.onPermissionGrant(permission);
                                    }
                                } else {
                                    if (null != deniedCallback) {
                                        deniedCallback.onPermissionDenied(permission);
                                    } else {
                                        onDefaultDenied(activity, permission);
                                    }
                                }
                            }
                        }
                    });
        } else if (null != fragment) {
            new RxPermissionsV4(fragment)
                    .requestEach(permissions)
                    .subscribe(new Consumer<Permission>() {
                        @Override
                        public void accept(Permission permission) {
                            if (null != permission) {
                                if (permission.granted) {
                                    if (null != grantCallback) {
                                        grantCallback.onPermissionGrant(permission);
                                    }
                                } else {
                                    if (null != deniedCallback) {
                                        deniedCallback.onPermissionDenied(permission);
                                    } else {
                                        onDefaultDenied(fragment.getActivity(), permission);
                                    }
                                }
                            }
                        }
                    });
        }
    }

    private void onDefaultDenied(
            final FragmentActivity activity,
            final Permission permission) {
        if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, permission.name)) {
            new AlertDialog.Builder(activity)
                    .setCancelable(true)
                    .setTitle(R.string.grant_fail_dialog_title)
                    .setMessage(R.string.grant_tip_message_to_setting)
                    .setPositiveButton(R.string.grant_btn_setting, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent intent = new Intent();
                            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
                            intent.setData(uri);
                            activity.startActivityForResult(intent, settingActivityRequestCode);
                            dialog.dismiss();
                        }
                    })
                    .setOnCancelListener(null == onDefaultDeniedDialogCancelListener ? new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            System.exit(0);
                        }
                    } : onDefaultDeniedDialogCancelListener)
                    .show();
        } else {
            new AlertDialog.Builder(activity)
                    .setCancelable(true)
                    .setTitle(R.string.grant_fail_dialog_title)
                    .setMessage(R.string.grant_tip_message)
                    .setPositiveButton(R.string.grant_btn_retry, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            requestPermission(permission.name);
                        }
                    })
                    .setOnCancelListener(null == onDefaultDeniedDialogCancelListener ? new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            System.exit(0);
                        }
                    } : onDefaultDeniedDialogCancelListener)
                    .show();
        }
    }

    public interface IOnPermissionGrant {
        void onPermissionGrant(Permission permission);
    }

    public interface IOnPermissionDenied {
        void onPermissionDenied(Permission permission);
    }
}
